#pragma once 
#include <OgreMath.h>
#include <OgreResourceManager.h>
#include <OgreBillboardSet.h>
#include <OgreBillboard.h>
#include <OgreSceneManager.h>
#include <vector>
#include <list>
#include "swMath.h"
#include "GameObject.h"
#include "Weapon.h"
#include "Skill.h"
class CCreature:public GameObject {
public:
    //CCreature();
    CCreature(const std::string &name, const std::string &scriptName );
    virtual ~CCreature();

    //=============================================
    GameInst* createInstance(const std::string &name);
public:
    float mPower;
    float mSpeed;
    float mDefence;
    float mLife;
    float mMana;
    std::string mTexture;
    std::vector<CWeapon> mWeapons;
    std::vector<CSkill>  mSkills;
};

class CCreatureInst: public GameInst {
public:
    CCreatureInst(CCreature *pObject, const std::string &name);
    virtual ~CCreatureInst();
    const Ogre::Vector3& getPosition() const {
        return mEntity->getParentSceneNode()->getPosition();
    }
    void setPosition(const Ogre::Vector3 &position) {
        mEntity->getParentNode()->setPosition(position);
    }

    //class Ogre::SceneNode* getParentSceneNode() const{
    //    return mEntity->getParentSceneNode();
    //}
    ////virtual void init();
    ////Ogre::MovableObject* getMovableObject() {
    ////    return mEntity;
    ////}
    //void attach(class Ogre::SceneNode *pSceneNode) {
    //    //if (mEntity->isAttached()) {
    //    //    mEntity->detachFromParent();
    //    //}
    //    pSceneNode->attachObject(mEntity);
    //}
    virtual bool isCollided(const class Ogre::MovableObject *obj) const{
        return intersects(getPosition(), mEntity->getBoundingRadius(), 
            obj->getParentSceneNode()->getPosition(), obj->getBoundingRadius());
    }
    virtual void move(const Ogre::Vector3 &direction, Ogre::Real time) {
        setPosition(getPosition() + direction*(mCurrentSpeed*time));
    }
    virtual void addWeapon(CWeaponInst*pWeapon, size_t slot = 0);
    CWeaponInst* removeWeapon(const std::string &name);
    CWeaponInst* removeWeapon(size_t slot);

    void setMaterialName(const std::string& name, const std::string& groupName  = Ogre::ResourceGroupManager::AUTODETECT_RESOURCE_GROUP_NAME );
    void setColor(const Ogre::ColourValue &color, int id = 0) {
        dynamic_cast<Ogre::BillboardSet*>(mEntity)->getBillboard(id)->setColour(color);
    }
    virtual void update(float dt);
protected:
    //class Ogre::BillboardSet * mEntity;

public:
    float mCurrentPower;
    float mCurrentSpeed;
    float mCurrentDefence;
    float mCurrentLife;
    float mCurrentMana;
    int mCurrentWeapon;
protected:
    std::vector<CWeaponInst*> mWeaponInsts;
    std::vector<CSkillInst*>  mSkillInsts;
};


class CNPC: public CCreature {
public:
    CNPC(const std::string &name, const std::string &scriptName = ""):CCreature(name, scriptName) {}
    GameInst* createInstance(const std::string &name);
    //std::list<CNPC*> mInstances;
};

class CNPCInst: public CCreatureInst {
public:
    CNPCInst(CNPC *pObject, const std::string &name);
};